package com.kkelectronics.w2b.devplugin.wizards.newdatabean;

import java.io.File;
import java.util.List;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jface.dialogs.IDialogPage;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;

import com.kkelectronics.w2b.beangen.service.FileFormattingException;
import com.kkelectronics.w2b.beangen.service.model.BeanClass;
import com.kkelectronics.w2b.beangen.service.model.BeanField;
import com.kkelectronics.w2b.devplugin.codegenerator.model.BeanParser;
import com.kkelectronics.w2b.devplugin.codegenerator.model.Field;

/**
 * The "New" wizard page allows setting the container for the new file as well
 * as the file name. The page will only accept file name without the extension
 * OR with the extension that matches the expected one (mpe).
 */

public class NewDataBeanWizardPage extends WizardPage {

	private static final int TEXT_WIDTH = 413;
	private static final int RIGHT_LABEL_WIDTH = 60;
	private static final String PACKAGE_PATCH = "\\src\\com\\kk_electronic\\w2b\\legacy\\datajs";
	private static final String PACKAGE = "com.kk_electronic.w2b.legacy.datajs";
	private static final String FSUFFIX_JS = "js";
	private static final String FSUFFIX_BEANS = "beans";
	private static final String FSUFFIX_INTERFACES = "interfaces";

	private static final BeanParser parser = new BeanParser();

	private final IPath packagePath;
	private final BeanClass beanClass;
	private final BeanClass interfaceClass;
	private final BeanClass jsClass;

	private List<Field> fields;

	private File file;

	private Text fileText;
	private Text interfaceText;
	private Text beanText;
	private Text jsText;
	private Table table;
	private TableViewer tableViewer;
	private TableColumn tblclmnType;
	private TableViewerColumn tableViewerColumn;
	private TableColumn tblclmnName;
	private TableViewerColumn tableViewerColumn_1;
	private TableColumn tblclmnEquals;
	private TableViewerColumn tableViewerColumn_2;
	private TableColumn tblclmnHashcode;
	private TableViewerColumn tableViewerColumn_3;
	private TableColumn tblclmnTostring;
	private TableViewerColumn tableViewerColumn_4;

	/**
	 * Constructor for SampleNewWizardPage.
	 * 
	 * @param pageName
	 */
	@SuppressWarnings("restriction")
	public NewDataBeanWizardPage(ISelection selection) {
		super("wizardPage");
		setTitle("Generate JS Bean");
		setDescription(".");
		packagePath = Path.fromOSString(((JavaProject) ((ITreeSelection) selection).getFirstElement()).getElementName() + PACKAGE_PATCH);

		beanClass = new BeanClass(PACKAGE + "." + FSUFFIX_BEANS, Path.fromOSString(((JavaProject) ((ITreeSelection) selection).getFirstElement()).getElementName() + PACKAGE_PATCH
				+ "\\" + FSUFFIX_BEANS));
		interfaceClass = new BeanClass(PACKAGE + "." + FSUFFIX_INTERFACES, Path.fromOSString(((JavaProject) ((ITreeSelection) selection).getFirstElement()).getElementName()
				+ PACKAGE_PATCH + "\\" + FSUFFIX_INTERFACES));
		jsClass = new BeanClass(PACKAGE + "." + FSUFFIX_JS, Path.fromOSString(((JavaProject) ((ITreeSelection) selection).getFirstElement()).getElementName() + PACKAGE_PATCH
				+ "\\" + FSUFFIX_JS));
	}

	/**
	 * Uses the standard container selection dialog to choose the new value for
	 * the container field.
	 */

	private void handleBrowse() {
		FileDialog dialog = new FileDialog(getShell());
		dialog.setFilterExtensions(new String[] { "*.cs" });
		String dialogResult = dialog.open();
		fileText.setText(dialogResult == null ? "" : dialogResult);
	}

	private void dialogChanged() {
		try {
			file = new File(fileText.getText());
			if (file.exists()) {
				updateStatus(null);
				String classComment = parser.getClassComment(file);

				interfaceClass.setClassName(genInterfaceName(file.getName()));
				interfaceClass.setClassComment(classComment);
				interfaceText.setText(PACKAGE + "." + FSUFFIX_INTERFACES + "." + interfaceClass.getClassName());

				beanClass.setClassName(genBeanName(file.getName()));
				beanClass.setClassComment(classComment);
				beanText.setText(PACKAGE + "." + FSUFFIX_BEANS + "." + beanClass.getClassName());

				jsClass.setClassName(genJSName(file.getName()));
				jsClass.setClassComment(classComment);
				jsText.setText(PACKAGE + "." + FSUFFIX_JS + "." + jsClass.getClassName());

				fields = parser.parseFileForFields(file);

				populateTable();

			} else {
				updateStatus("File container must be specified");
			}
		} catch (FileFormattingException e) {
			updateStatus(e.getLocalizedMessage());
		}
	}

	private void populateTable() {
		//		table.set
	}

	private String genInterfaceName(String name) {
		return "I" + name.substring(0, name.indexOf("."));
	}

	private String genBeanName(String name) {
		return name.substring(0, name.indexOf(".")) + "Bean";
	}

	private String genJSName(String name) {
		return name.substring(0, name.indexOf(".")) + "JS";
	}

	private void updateStatus(String message) {
		setErrorMessage(message);
		setPageComplete(message == null);
	}

	public String getFilePath() {
		return fileText.getText();
	}

	public File getFile() {
		return file;
	}

	/**
	 * @see IDialogPage#createControl(Composite)
	 */
	@Override
	public void createControl(Composite parent) {

		Composite wrapper = new Composite(parent, SWT.FILL);
		GridLayout layout = new GridLayout();
		wrapper.setLayout(layout);
		layout.verticalSpacing = 9;

		Composite container = new Composite(wrapper, SWT.FILL);
		container.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		layout = new GridLayout();
		container.setLayout(layout);
		layout.numColumns = 3;
		layout.verticalSpacing = 9;

		// package row
		Label label = new Label(container, SWT.NULL);
		GridData gd_label = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_label.widthHint = RIGHT_LABEL_WIDTH;
		label.setLayoutData(gd_label);
		label.setText("&Package:");

		label = new Label(container, SWT.NONE);
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		label.setText(packagePath.toOSString());

		new Label(container, SWT.NONE);

		// file dialog row
		label = new Label(container, SWT.NULL);
		gd_label = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_label.widthHint = RIGHT_LABEL_WIDTH;
		label.setLayoutData(gd_label);
		label.setText("&Path:");

		fileText = new Text(container, SWT.BORDER | SWT.SINGLE);
		GridData gd_fileText = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
		gd_fileText.widthHint = TEXT_WIDTH;
		fileText.setLayoutData(gd_fileText);
		fileText.setEditable(false);
		fileText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});

		Button button = new Button(container, SWT.PUSH);
		button.setText("Browse...");
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleBrowse();
			}
		});

		// separator
		Label separator = new Label(wrapper, SWT.SEPARATOR | SWT.HORIZONTAL);
		separator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));

		// Bean details
		Composite details = new Composite(wrapper, SWT.FILL);
		details.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		layout = new GridLayout();
		details.setLayout(layout);
		layout.numColumns = 3;
		layout.verticalSpacing = 9;

		label = new Label(details, SWT.NULL);
		gd_label = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_label.widthHint = RIGHT_LABEL_WIDTH;
		label.setLayoutData(gd_label);
		label.setText("&Interface:");

		interfaceText = new Text(details, SWT.BORDER | SWT.SINGLE);
		gd_fileText = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
		gd_fileText.widthHint = TEXT_WIDTH;
		interfaceText.setLayoutData(gd_fileText);
		interfaceText.setEditable(false);

		new Label(details, SWT.NONE);

		label = new Label(details, SWT.NULL);
		gd_label = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_label.widthHint = RIGHT_LABEL_WIDTH;
		label.setLayoutData(gd_label);
		label.setText("&Bean:");

		beanText = new Text(details, SWT.BORDER | SWT.SINGLE);
		gd_fileText = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
		gd_fileText.widthHint = TEXT_WIDTH;
		beanText.setLayoutData(gd_fileText);
		beanText.setEditable(false);

		new Label(details, SWT.NONE);

		label = new Label(details, SWT.NULL);
		gd_label = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_label.widthHint = RIGHT_LABEL_WIDTH;
		label.setLayoutData(gd_label);
		label.setText("&JS:");

		jsText = new Text(details, SWT.BORDER | SWT.SINGLE);
		gd_fileText = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
		gd_fileText.widthHint = TEXT_WIDTH;
		jsText.setLayoutData(gd_fileText);
		jsText.setEditable(false);

		new Label(details, SWT.NONE);

		tableViewer = new TableViewer(wrapper, SWT.BORDER | SWT.FULL_SELECTION);
		table = tableViewer.getTable();
		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

		tableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
		tblclmnType = tableViewerColumn.getColumn();
		tblclmnType.setWidth(100);
		tblclmnType.setText("Type");

		tableViewerColumn_1 = new TableViewerColumn(tableViewer, SWT.NONE);
		tblclmnName = tableViewerColumn_1.getColumn();
		tblclmnName.setWidth(100);
		tblclmnName.setText("Name");

		tableViewerColumn_2 = new TableViewerColumn(tableViewer, SWT.NONE);
		tblclmnEquals = tableViewerColumn_2.getColumn();
		tblclmnEquals.setResizable(false);
		tblclmnEquals.setWidth(100);
		tblclmnEquals.setText("equals()");

		tableViewerColumn_3 = new TableViewerColumn(tableViewer, SWT.NONE);
		tblclmnHashcode = tableViewerColumn_3.getColumn();
		tblclmnHashcode.setResizable(false);
		tblclmnHashcode.setWidth(100);
		tblclmnHashcode.setText("hashCode()");

		tableViewerColumn_4 = new TableViewerColumn(tableViewer, SWT.NONE);
		tblclmnTostring = tableViewerColumn_4.getColumn();
		tblclmnTostring.setResizable(false);
		tblclmnTostring.setWidth(100);
		tblclmnTostring.setText("toString()");

		dialogChanged();
		setControl(wrapper);
	}

	public List<Field> getFields() {
		return fields;
	}

	public BeanClass getBeanClass() {
		return beanClass;
	}

	public BeanClass getInterfaceClass() {
		return interfaceClass;
	}

	public BeanClass getJsClass() {
		return jsClass;
	}

	public String getBeanFileName() {
		return beanClass.getClassName();
	}

	public String getInterfaceFileName() {
		return interfaceClass.getClassName();
	}

	public String getJsFileName() {
		return jsClass.getClassName();
	}
}